//+--------------------------------------------------------------------
//| Copyright(c) 2012 - an.vuongngocduy					
//| This file is a part of Compact Game Engine (CGE)	
//+--------------------------------------------------------------------
#ifndef __CGE_SIZE2_H__
#define __CGE_SIZE2_H__

#include "cgeCommons.h"
#include "cgeProperty.h"

namespace cge
{
	namespace std
	{
		template<class TVal>
		class Size2
		{
		public:
			/// Default constructor
			Size2()
				: Width(0), Height(0)
			{}

			/// Copy constructor
			template<class TArg>
			Size2(const Size2<TArg>& sz)
				: Width(sz.Width), Height(sz.Height)
			{}

			/// Construct new size from specified values
			Size2(TVal w, TVal h)
				: Width(w), Height(h)
			{}

			/// Set values for size
			void Set(TVal w, TVal h)
			{
				Width = w;	Height = h;
			}

			/// Return the area of current rectangle
			TVal Area() const
			{
				TVal w = Right - Left;
				TVal h = Bottom - Top;
				return (w * h);
			}

			/// Return perimeter of current rectangle
			TVal Perimeter() const
			{
				return 2 * (Width + Height);
			}

			template<class TArg>
			Size2 operator * (TArg scalar) const
			{
				return Size2(Width * scalar, Height * scalar);
			}

			template<class TArg>
			Size2 operator / (TArg scalar) const
			{
				return Size2(Width / scalar, Height / scalar);
			}

			template<class TArg>
			friend Size2 operator + (const Size2& lsz, const Size2<TArg>& rsz)
			{
				return Size2(lsz.Width + rsz.Width , lsz.Height + rsz.Height);
			}

			template<class TArg>
			friend Size2 operator - (const Size2& lsz, const Size2<TArg>& rsz)
			{
				return Size2(lsz.Width - rsz.Width , lsz.Height - rsz.Height);
			}

			template<class TArg>
			friend b8 operator == (const Size2& lsz, const Size2<TArg>& rsz)
			{
				return (lsz.Width == (TVal)rsz.Width) && (lsz.Height == (TVal)rsz.Height);
			}

			template<class TArg>
			friend b8 operator != (const Size2& lsz, const Size2<TArg>& rsz)
			{
				return (lsz.Width != (TVal)rsz.Width) || (lsz.Height != (TVal)rsz.Height);
			}

			template<class TArg>
			Size2& operator *= (TArg scalar)
			{
				Width *= scalar;	Height *= scalar;
				return *this;
			}

			template<class TArg>
			Size2& operator /= (TArg scalar)
			{
				Width /= scalar;	Height /= scalar;
				return *this;
			}

			template<class TArg>
			Size2& operator + (const Size2<TArg>& sz)
			{
				Width += sz.Width;		Height += sz.Height;
				return *this;
			}

			template<class TArg>
			Size2& operator - (const Size2<TArg>& sz)
			{
				Width -= sz.Width;		Height -= sz.Height;
				return *this;
			}

			template<class TArg>
			Size2& operator = (const Size2<TArg>& sz)
			{
				Set(sz.Width, sz.Height);
				return *this;
			}

		public:
			union
			{
				struct { TVal Width, Height; };
				TVal Dimension[2];
			};
		};

		typedef Size2<u32> Size2u;
	}
}

#endif//__CGE_SIZE2_H__